package com.woniu.mealsService.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.StringUtil;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.dto.CommentDto;
import com.woniu.dto.OrderDto;
import com.woniu.exception.XinanException;
import com.woniu.exception.meals.FeignException;
import com.woniu.exception.meals.MealsException;
import com.woniu.exception.meals.OrderException;
import com.woniu.exception.meals.StoreException;
import com.woniu.form.ProductForm;
import com.woniu.mealsService.config.AliPayConfig;
import com.woniu.mealsService.data.OrderStatus;
import com.woniu.mealsService.mapper.*;
import com.woniu.mealsService.model.*;
import com.woniu.mealsService.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.mealsService.util.Data;
import com.woniu.mealsService.util.DateUtils;
import com.woniu.param.AddOrderParam;
import com.woniu.param.GetPageOrderParam;
import com.woniu.pojo.AlipayBean;
import com.woniu.pojo.AlipayQueryBean;
import com.woniu.server.RedisKey;
import com.woniu.server.RedisUtil;
import com.woniu.user.client.UserFeignClient;
import com.woniu.user.dto.UserInfoFeignDto;
import com.woniu.utils.EnumException;
import com.woniu.utils.PageInfo;
import com.woniu.utils.Result;
import org.jetbrains.annotations.NotNull;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.SchedulingConfiguration;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author jiang
 * @since 2024年12月10日
 */
@Service
@Transactional
public class OrderProductServiceImpl extends ServiceImpl<OrderProductMapper, OrderProduct> implements OrderProductService {
    @Autowired
    private StoreService storeService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private OrderLogMapper orderLogMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private AliPayConfig aliPayConfig;
    @Autowired
    private OrderLogService orderLogService;
    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private StoreProductMapper storeProductMapper;
    @Autowired
    private AddressService addressService;
    @Autowired
    private StoreVIewMapper storeVIewMapper;
    @Override
    public Map<Long,List<String>> selectRate() {
        List<Store> stores = storeService.selectAllStore();
        Map<Long,List<String>> storeMap = new HashMap<>();
        stores.forEach(store -> {
            List<String> collect = orderProductMapper.selectOrderIdByStoreId(store.getStoreId());
            storeMap.put(store.getStoreId(), collect);
        });
        return storeMap;
    }

    @Override
    public PageInfo<OrderDto> getPageOrder(GetPageOrderParam bean) throws Exception {
        Page<OrderProduct> page = new Page<>(bean.getPageNum(), bean.getPageSize());
        LambdaQueryWrapper<OrderProduct> queryWrapper = new LambdaQueryWrapper<>();
        Long storeId = null;
        if (bean.getUserId()!=null && bean.getRoleId() == 2) {
            for (Store store : storeMapper.selectAllStore()) {
                if (Long.valueOf(store.getUserId()).compareTo(bean.getUserId())==0) {
                    storeId = store.getStoreId();
                    break;
                }
            }
            queryWrapper.eq(OrderProduct::getStoreId, storeId);
        }

        if (!StringUtil.isNullOrEmpty(bean.getOrderNum())) {
            queryWrapper.eq(OrderProduct::getOrderId, bean.getOrderNum());
        }
        if (!StringUtil.isNullOrEmpty(bean.getUserPhone())) {
            List<Address> list = addressService.list(new LambdaQueryWrapper<Address>().eq(Address::getConsigneePhone, bean.getUserPhone()));
            List<Long> collect = list.stream().map(Address::getAddressId).collect(Collectors.toList());
            if (collect.size() == 0) {
                throw new RuntimeException("没有该用户的订单");
            }
            queryWrapper.in(OrderProduct::getUserAddress, collect);
        }
        if (!StringUtil.isNullOrEmpty(bean.getStoreName())) {
            queryWrapper.like(OrderProduct::getStoreName, bean.getStoreName());
        }
        if(!StringUtil.isNullOrEmpty(bean.getUserName())){
            queryWrapper.like(OrderProduct::getUserName, bean.getUserName());
        }
        if (!StringUtil.isNullOrEmpty(bean.getUserAddress())){
            List<Address> list = addressService.list(new LambdaQueryWrapper<Address>().like(Address::getAddressName, bean.getUserAddress()));
            List<Long> collect = list.stream().map(Address::getAddressId).collect(Collectors.toList());
            queryWrapper.in(OrderProduct::getUserAddress, collect);
        }
        if (bean.getUserId()!=null && bean.getRoleId() == 1 ) {
            queryWrapper.eq(OrderProduct::getUserId, bean.getUserId());
        }
        if (bean.getUserId()!=null && bean.getRoleId() == 4 ) {
            queryWrapper.eq(OrderProduct::getUserId, bean.getUserId());
        }
        if (bean.getOrderStatus()!=null && bean.getOrderStatus() >= 0 && bean.getOrderStatus() <= 9){
            queryWrapper.eq(OrderProduct::getOrderState, bean.getOrderStatus());
        }
        if (!StringUtil.isNullOrEmpty(bean.getOrderStartTime())) {
            queryWrapper.ge(OrderProduct::getCreateTime, bean.getOrderStartTime());
        }
        if (!StringUtil.isNullOrEmpty(bean.getOrderEndTime())) {
            queryWrapper.le(OrderProduct::getCreateTime, bean.getOrderEndTime());
        }
        queryWrapper.orderByDesc(OrderProduct::getCreateTime);
        orderProductMapper.selectPage(page, queryWrapper);
        PageInfo<OrderDto> orderDtoPageInfo = new PageInfo<>(page, OrderDto.class);
        for (OrderDto orderDto : orderDtoPageInfo.getList()) {
            System.out.println(orderDto);
            Address address = addressService.getOne(new QueryWrapper<Address>().eq("address_id", Long.parseLong(orderDto.getUserAddress())));
            if (null == address){
                throw new MealsException(EnumException.ADDRESS_NULL_EXCEPTION);
            }
            orderDto.setConsignee(address.getConsignee());
            orderDto.setConsigneePhone(address.getConsigneePhone());
            orderDto.setAddressName(address.getAddressName());
        }
        return orderDtoPageInfo;
    }

    @Override
    public OrderDto getOrder(String orderId) throws Exception {
        OrderProduct orderProduct = this.getById(orderId);
        if (orderProduct == null) {
            throw new OrderException(EnumException.ORDER_NULL_EXCEPTION);
        }
        OrderDto orderDto = new OrderDto();
        BeanUtil.copyProperties(orderProduct, orderDto);
        Address address = addressService.getOne(new QueryWrapper<Address>().eq("address_id", Long.parseLong(orderDto.getUserAddress())));
        if (null == address){
            throw new MealsException(EnumException.ADDRESS_NULL_EXCEPTION);
        }
        orderDto.setConsignee(address.getConsignee());
        orderDto.setConsigneePhone(address.getConsigneePhone());
        orderDto.setAddressName(address.getAddressName());
        return orderDto;
    }

    @Override
    //添加订单
    public String addOrder(@NotNull AddOrderParam bean) throws Exception {
//        if (redisUtil.exists(RedisKey.addOrder(bean.getUserId()))) {
//            return "请稍后下单";
//        }
//        redisUtil.set(RedisKey.addOrder(bean.getUserId()), "1", 5);

        LocalDateTime now = LocalDateTime.now();
        String time = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Store store = storeService.getById(bean.getStoreId());
        if (store == null) {
            throw new StoreException(EnumException.STORE_NULL_EXCEPTION);
        }
        String format = now.toLocalTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        if (Time.valueOf(format).before(store.getStoreStartTime())||Time.valueOf(format).after(store.getStoreEndTime())){
            throw new StoreException(EnumException.STORE_TIME_EXCEPTION);
        }
        Double totalPrice = storeProductService.getTotalPrice(bean.getProductIds());
        System.out.println("totalPrice:"+totalPrice+"  OrderAmount:"+bean.getOrderAmount());
        if (Double.compare(totalPrice, Double.parseDouble(bean.getOrderAmount()))!=0){
            throw new OrderException(EnumException.ORDER_ACCOUNT_EXCEPTION);
        }
        Store storeServiceOne = storeService.getOne(new LambdaQueryWrapper<Store>().eq(Store::getStoreId, bean.getStoreId()));
        String orderId = new Snowflake(1, 1).nextIdStr();
        OrderProduct orderProduct = new OrderProduct();
        orderProduct.setOrderId(orderId);
        orderProduct.setUserAddress(bean.getUserAddress());
        orderProduct.setPayMethod("支付宝");
        if (storeServiceOne.getStatus() == 0) {

            System.out.println(bean.getUserAddress());
            BeanUtil.copyProperties(bean, orderProduct);
            String productIds = JSONUtil.toJsonStr(bean.getProductIds());
            orderProduct.setProductIds(productIds);
            System.out.println(productIds);
            orderProduct.setOrderAmount(new BigDecimal(bean.getOrderAmount()));
            orderProduct.setOrderState(7);
            orderProduct.setUserAddress(bean.getUserAddress());
            orderProduct.setCreateTime(time);
            this.save(orderProduct);
            rabbitTemplate.convertAndSend("delay_Update_Order", orderId);
            OrderLog orderLog = new OrderLog();
            orderLog.setOrderId(orderProduct.getOrderId());
            orderLog.setStatus("7");
            orderLog.setOrderDesc("等待商家接单");
            orderLog.setCreateTime(time);
            orderLogMapper.insert(orderLog);
        } else {
            System.out.println(bean.getUserAddress());
            BeanUtil.copyProperties(bean, orderProduct);
            String productIds = JSONUtil.toJsonStr(bean.getProductIds());
            orderProduct.setProductIds(productIds);
            orderProduct.setOrderAmount(new BigDecimal(bean.getOrderAmount()));
            orderProduct.setOrderState(0);
            orderProduct.setUserAddress(bean.getUserAddress());
            orderProduct.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            this.save(orderProduct);
            OrderLog orderLog = new OrderLog();
            orderLog.setOrderId(orderProduct.getOrderId());
            orderLog.setStatus("0");
            orderLog.setOrderDesc("等待用户支付");
            orderLog.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderProduct.setUserAddress(bean.getUserAddress());
            orderLogMapper.insert(orderLog);
        }

        redisUtil.removeSet(RedisKey.shoppingCarts(bean.getUserId()),bean.getStoreId());
        redisUtil.delete(RedisKey.shoppingCart(bean.getUserId(),bean.getStoreId()));
        return orderId;
    }

    @Override
    //手动接单
    public String takOrder(String orderId, String userId) throws Exception {
        OrderProduct orderProduct = this.getById(orderId);
        if (orderProduct == null) {
            throw new OrderException(EnumException.ORDER_NULL_EXCEPTION);
        }
        if (orderProduct.getOrderState() != 7) {
            throw new OrderException(EnumException.ORDER_STATE_EXCEPTION);
        }
        orderProduct.setOrderState(0);
        orderProduct.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        boolean b = this.updateById(orderProduct);
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderProduct.getOrderId());
        orderLog.setStatus("0");
        orderLog.setOrderDesc("等待用户支付");
        orderLog.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        orderLogMapper.insert(orderLog);
        return b ? "接单成功" : "接单失败";
    }

    @Override
    //取消订单操作
    public String cancelOrder(String orderId,String userId,String roleId) throws Exception {
        OrderProduct orderProduct = this.getById(orderId);
        try {
            if (orderProduct == null) {
                throw new OrderException(EnumException.ORDER_NULL_EXCEPTION);
            }
            OrderLog orderLog = new OrderLog();
            String cancelTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

            orderLog.setOrderId(orderProduct.getOrderId());
            orderLog.setStatus("5");
            orderLog.setCreateTime(cancelTime);
            if (orderProduct.getOrderState() == 8) {
                throw new OrderException("订单已关闭,无法取消订单", 10005);
            }
            if (orderProduct.getOrderState() == 5) {
                throw new OrderException("订单已取消", 10005);
            }
            if (orderProduct.getOrderState() == 7){
                orderProduct.setOrderState(5);
                orderProduct.setCancelledTime(cancelTime);
                orderLog.setOrderDesc("用户取消订单");
                orderLogMapper.insert(orderLog);
                boolean b = this.updateById(orderProduct);
                return b ? "取消订单成功" : "取消订单失败";
            }
            if (orderProduct.getOrderState() == 0) {
                orderProduct.setOrderState(5);
                orderProduct.setCancelledTime(cancelTime);
                orderLog.setOrderDesc("用户取消订单");
                orderLogMapper.insert(orderLog);
                boolean b = this.updateById(orderProduct);
                return b ? "取消订单成功" : "取消订单失败";
            } else if (orderProduct.getOrderState() == 2|| orderProduct.getOrderState() == 1) {
                if (roleId.equals("1")){
                    throw new OrderException("商家备餐中，无法取消订单", 10005);
                }else if (roleId.equals("2")){
                    orderProduct.setOrderState(5);
                    orderProduct.setCancelledTime(cancelTime);
                    orderLog.setOrderDesc("用户申请，商家同意取消订单");
                    orderLogMapper.insert(orderLog);
                    boolean b = this.updateById(orderProduct);
                    if (b){
                        this.refundOrder(orderId);
                    }
                    return b ? "取消订单成功" : "取消订单失败";
                }
            }else if (orderProduct.getOrderState() == 3 || orderProduct.getOrderState()==4) {
                throw new OrderException("订单已配送,无法取消订单", 10005);
            }
            throw new OrderException("订单状态异常", 10005);
        }catch (Exception e){
            if (e instanceof XinanException){
                throw e;
            }
            return e.getMessage();
        }
    }

    @Override
    //发起支付
    public String pay(String orderId, String userId) throws Exception {
        OrderProduct one = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId).eq(OrderProduct::getUserId, userId).eq(OrderProduct::getOrderState, 0));
        try {
            if (one == null) {
                throw new OrderException("订单已支付或订单已取消", 10005);
            }
            System.out.println(one.getCreateTime());
            AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
            //页面跳转同步通知页面路径
            alipayTradePagePayRequest.setReturnUrl(aliPayConfig.getReturn_url());
            // 服务器异步通知页面路径
            alipayTradePagePayRequest.setNotifyUrl(aliPayConfig.getNotify_url());
            AlipayBean alipayBean = new AlipayBean();
            alipayBean.setOut_trade_no(orderId);
            // 设置订单金额
            alipayBean.setTotal_amount(one.getOrderAmount().doubleValue());
            String substring = one.getCreateTime().substring(0, 19);
            String format = Objects.requireNonNull(DateUtils.getLocalDateTime(DateUtils.getTime(substring))).plusMinutes(15).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            System.out.println(format);
            alipayBean.setTime_expire(format);
            System.out.println(alipayBean);
            String jsonAlipayBean = JSONUtil.toJsonStr(alipayBean);
            alipayTradePagePayRequest.setBizContent(jsonAlipayBean);
            AlipayTradePagePayResponse alipayTradePagePayResponse = alipayClient.pageExecute(alipayTradePagePayRequest);
            if (alipayTradePagePayResponse.isSuccess()) {
                rabbitTemplate.convertAndSend("delay_alipay_status", orderId);
                return alipayTradePagePayResponse.getBody();
            }

            throw new OrderException(EnumException.ALIPAY_ERROR_EXCEPTION);
        }catch (Exception e){
            if (e instanceof XinanException){
                throw e;
            }
            return e.getMessage();
        }
    }

    @Override
    // 订单支付成功，更新订单状态
    public String updateOrder(String outTradeNo, Integer OrderState) throws Exception {
        OrderProduct order = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, outTradeNo));
        try {
            if (null == order) {
                throw new OrderException(EnumException.ORDER_NULL_EXCEPTION);
            }
            OrderLog deliveryLog  = null;
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            if (OrderStatus.ORDER_PAID.equals(OrderState)){
                if (!OrderStatus.ORDER_NOPAY.equals(order.getOrderState())) {
                    throw new OrderException(EnumException.ORDER_STATE_EXCEPTION);
                }
                order.setOrderState(OrderStatus.ORDER_PREPARATION);
                order.setPayTime(time);
                OrderLog payLog = new OrderLog();
                payLog.setOrderId(order.getOrderId());
                payLog.setStatus(OrderState.toString());
                payLog.setOrderDesc(OrderStatus.statusMap.get(OrderState));
                payLog.setCreateTime(time);
                OrderLog prepareLog = new OrderLog();
                prepareLog.setOrderId(order.getOrderId());
                prepareLog.setStatus(String.valueOf(OrderStatus.ORDER_PREPARATION));
                prepareLog.setOrderDesc(OrderStatus.statusMap.get(OrderStatus.ORDER_PREPARATION));
                prepareLog.setCreateTime(time);
                List<OrderLog> orderLogs = new ArrayList<>();
                orderLogs.add(payLog);
                orderLogs.add(prepareLog);
                orderLogService.saveBatch(orderLogs);
                this.updateById(order);
                return "更新成功";
            }else if (OrderStatus.ORDER_DELIVERY.equals(OrderState)){
                if (!OrderStatus.ORDER_PREPARATION.equals(order.getOrderState())){
                    throw new OrderException("订单未支付或已取消", 10005);
                }
                order.setOrderState(OrderStatus.ORDER_DELIVERY);
                order.setDeliveryTime(time);
                deliveryLog = new OrderLog();
                deliveryLog.setOrderId(order.getOrderId());
                deliveryLog.setStatus(OrderState.toString());
                deliveryLog.setOrderDesc(OrderStatus.statusMap.get(OrderState));
                deliveryLog.setCreateTime(time);
                this.updateById(order);
                orderLogService.save(deliveryLog);
                return "更新成功";
            }else if (OrderStatus.ORDER_DELIVERED.equals(OrderState)){
                if (!OrderStatus.ORDER_DELIVERY.equals(order.getOrderState())){
                    throw new OrderException(EnumException.ORDER_STATE_EXCEPTION);
                }
                order.setOrderState(OrderStatus.ORDER_DELIVERED);
                order.setDeliveredTime(time);
                OrderLog deliveredLog = new OrderLog();
                deliveredLog.setOrderId(order.getOrderId());
                deliveredLog.setStatus(OrderState.toString());
                deliveredLog.setOrderDesc(OrderStatus.statusMap.get(OrderState));
                deliveredLog.setCreateTime(time);
                this.updateById(order);
                orderLogService.save(deliveredLog);
                rabbitTemplate.convertAndSend("delay_order_close",order.getOrderId());
                return "更新成功";
            }
            throw new OrderException("更新失败", 10005);
        }catch (Exception e){
            if (e instanceof XinanException){
                throw e;
            }
            return e.getMessage();
        }
    }

    @Override
    // 订单支付出现错误或者网络延迟，订单支付补偿操作
    public String alipayQuery(String orderId) throws Exception {
        OrderProduct order = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId));
        if (null == order) {
            throw new OrderException(EnumException.ORDER_NULL_EXCEPTION);
        }
        if (OrderStatus.ORDER_PAID.equals(order.getOrderState())) {
            return "订单已支付";
        }
        if (OrderStatus.ORDER_DELIVERED.equals(order.getOrderState())) {
            return "订单已送达";
        }
        if (OrderStatus.ORDER_DELIVERY.equals(order.getOrderState())) {
            return "订单已配送";
        }
        if (OrderStatus.ORDER_CANCEL.equals(order.getOrderState())) {
            return "订单已取消";
        }
        if (OrderStatus.ORDER_REFUNDED.equals(order.getOrderState())) {
            return "订单已退款";
        }
        if (OrderStatus.ORDER_STORETAKE.equals(order.getOrderState())) {
            return "等待商家接单";
        }
        if (OrderStatus.ORDER_CLOSED.equals(order.getOrderState())) {
            return "订单已关闭";
        }
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        AlipayQueryBean alipayQueryBean = new AlipayQueryBean();
        alipayQueryBean.setOut_trade_no(orderId);
        String queryBean = JSONUtil.toJsonStr(alipayQueryBean);
        request.setBizContent(queryBean);
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        System.out.println(response);
        if (response.isSuccess()) {
            String tradeStatus = response.getTradeStatus();
            if ("TRADE_SUCCESS".equals(tradeStatus)) {
                OrderProduct one = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId).eq(OrderProduct::getOrderState, 0));
                String payTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if (null != one) {
                    if (OrderStatus.ORDER_NOPAY.equals(one.getOrderState())){
                        one.setPayTime(payTime);
                        one.setOrderState(2);
                        OrderLog orderLog = new OrderLog();
                        orderLog.setOrderId(one.getOrderId());
                        orderLog.setStatus("1");
                        orderLog.setOrderDesc("用户已支付订单");
                        orderLog.setCreateTime(payTime);
                        orderLogMapper.insert(orderLog);
                        OrderLog prepareLog = new OrderLog();
                        prepareLog.setOrderId(one.getOrderId());
                        prepareLog.setStatus("2");
                        prepareLog.setOrderDesc("商家准备中");
                        prepareLog.setCreateTime(payTime);
                        orderLogMapper.insert(prepareLog);
                        this.updateById(one);
                        return "TRADE_SUCCESS";
                    }else if (OrderStatus.ORDER_PAID.equals(one.getOrderState())){
                        OrderLog orderLog = new OrderLog();
                        orderLog.setOrderId(one.getOrderId());
                        orderLog.setStatus("1");
                        orderLog.setOrderDesc("用户已支付订单");
                        orderLog.setCreateTime(payTime);
                        orderLogMapper.insert(orderLog);
                        return "TRADE_SUCCESS";
                    }else {
                        return "TRADE_SUCCESS";
                    }
                }
            } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                return "TRADE_CLOSED";
            } else if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
                rabbitTemplate.convertAndSend("delay_alipay_status", orderId);
                return "WAIT_BUYER_PAY";
            }else if("TRADE_FINISHED".equals(tradeStatus)){
                return "TRADE_FINISHED";
            }
        }else {
            Map<String,String> map = new HashMap<>();
            String code = response.getCode();
            String subMsg = response.getSubMsg();
            map.put("code",code);
            map.put("subMsg",subMsg);
            map.put("orderId",orderId);
            rabbitTemplate.convertAndSend("error_order", map);
        }
        return "TRADE_ERROR";
    }
    // 订单关闭操作
    @Override
    public String closeOrder(String orderId) throws Exception {
        OrderProduct one = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId).eq(OrderProduct::getOrderState, 4));
        try {
            if (null == one) {
                throw new OrderException("订单不存在", 10005);
            }
            if (4 != one.getOrderState()){
                throw new OrderException(EnumException.ORDER_STATE_EXCEPTION);
            }
            Comment select = commentMapper.select(null, null, one.getOrderId(), one.getUserId());
            if (select==null){
                Result<UserInfoFeignDto> userInfo = userFeignClient.getUserInfo(one.getUserId());
                if (userInfo.getCode()!=200){
                    throw new FeignException(EnumException.NET_ERROR_EXCEPTION);
                }
                Comment comment = new Comment();
                comment.setStoreId(one.getStoreId());
                comment.setOrderId(orderId);
                comment.setUserId(one.getUserId());
                comment.setRate(5);
                comment.setUserName(one.getUserName());
                comment.setUserImg(userInfo.getData().getUserImg());
                commentMapper.insert(comment);
            }
            one.setOrderState(8);
            String closeTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            one.setCloseTime(closeTime);
            OrderLog orderLog = new OrderLog();
            orderLog.setOrderId(one.getOrderId());
            orderLog.setStatus("8");
            orderLog.setOrderDesc("订单已关闭");
            orderLog.setCreateTime(closeTime);
            int insert = orderLogMapper.insert(orderLog);
            return "订单已关闭";
//            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
//            Map<String,String> params = new HashMap<>();
//            params.put("out_trade_no",orderId);
//            String outTradeNo = JSONUtil.toJsonStr(params);
//            request.setBizContent(outTradeNo);
//            AlipayTradeCloseResponse response = alipayClient.execute(request);
//            if (response.isSuccess()){
//
//            }else {
//                Map<String,String> map = new HashMap<>();
//                String code = response.getCode();
//                String subMsg = response.getSubMsg();
//                map.put("code",code);
//                map.put("subMsg",subMsg);
//                map.put("orderId",orderId);
//                rabbitTemplate.convertAndSend("error_order", map);
//            }
//            return "订单关闭失败";
        }catch (Exception e){
            if (e instanceof XinanException){
                throw e;
            }
            return e.getMessage();
        }
    }

    @Override
    public String refundOrder(String orderId) throws Exception {
        OrderProduct one = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId).eq(OrderProduct::getOrderState, 5));
        OrderLog refund = new OrderLog();
        refund.setOrderDesc("商户已退款");
        refund.setStatus("6");
        refund.setOrderId(one.getOrderId());
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        Map<String,String> params = new HashMap<>();
        params.put("out_trade_no",orderId);
        params.put("refund_amount",String.valueOf(one.getOrderAmount().doubleValue()));
        String refundBean = JSONUtil.toJsonStr(params);
        request.setBizContent(refundBean);
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()){
            String code = response.getCode();
            Date gmtRefundPay = response.getGmtRefundPay();
            String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(gmtRefundPay);
            if ("10000".equals(code)){
                one.setOrderState(6);
                one.setRefundedTime(format);
                refund.setCreateTime(format);
                this.updateById(one);
                orderLogService.save(refund);
                return "退款成功";
            }
        }else {
            Map<String,String> map = new HashMap<>();
            String code = response.getCode();
            String subMsg = response.getSubMsg();
            map.put("code",code);
            map.put("subMsg",subMsg);
            map.put("orderId",orderId);
            rabbitTemplate.convertAndSend("error_order", map);
        }
        return "退款失败";
    }

    @Override
    @Transactional
    public void calculateSales(Long storeId) throws Exception {
        LocalDateTime now = LocalDateTime.now();
        String date = now.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDateTime midnight = now.toLocalDate().plusDays(1).atStartOfDay();
        // 获取当前日期的开始时间
        LocalDateTime startDate = LocalDate.now().atStartOfDay();
        // 获取当前日期的结束时间
        LocalDateTime endDate = LocalDate.now().atTime(LocalTime.MAX);
        Store store = storeMapper.selectById(storeId);
        if (store==null){
            throw new StoreException(EnumException.STORE_NULL_EXCEPTION);
        }
        StoreView storeView = storeVIewMapper.selectOne(storeId,date);
        if(now.equals(midnight)||now.isAfter(midnight)||storeView==null){
            if (redisUtil.exists(RedisKey.saveStorePopularFood(String.valueOf(storeId)))){
                redisUtil.del(RedisKey.saveStorePopularFood(String.valueOf(storeId)));
            }
            List<OrderProduct> list = this.list(new LambdaQueryWrapper<OrderProduct>().between(OrderProduct::getCreateTime, startDate, endDate).eq(OrderProduct::getStoreId, storeId).in(OrderProduct::getOrderState, 4,8));
            storeView = new StoreView();
            storeView.setStoreId(storeId);
            storeView.setDateTime(date);
            storeView.setCreatTime(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            storeView.setTotalCount(list.size());
            storeView.setTotalSales(list.stream().map(OrderProduct::getOrderAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
            storeView.setTag(Data.TAG_TYPE_DAILY);
            this.popularFood(storeId,list);
            storeView.setPopularProduct(String.valueOf(redisUtil.zrerange(RedisKey.saveStorePopularFood(String.valueOf(storeId)),0,1)));
            List<OrderProduct> orderProducts = orderProductMapper.selectList(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getStoreId, storeId).orderByDesc(OrderProduct::getCreateTime).in(OrderProduct::getOrderState, 4,8).last("limit 10"));
            Integer rate = 0;
            for (OrderProduct orderProduct : orderProducts) {
                Comment comment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().eq(Comment::getOrderId, orderProduct.getOrderId()));
                if (comment!=null){
                    rate+=comment.getRate();
                }
            }
            if (orderProducts.size() == 0){
                throw new RuntimeException("没有订单");
            }
            Integer newRate = rate/ orderProducts.size();
            storeView.setRate(newRate);
            store.setStoreScore(String.valueOf(newRate));
            storeVIewMapper.insertDailyStoreView(storeView);
            storeService.updateById(store);
        }else {
            List<OrderProduct> list = this.list(new LambdaQueryWrapper<OrderProduct>().between(OrderProduct::getCreateTime, startDate, endDate).eq(OrderProduct::getStoreId, storeId).in(OrderProduct::getOrderState, 4,8));
            if(storeView == null){
                throw new RuntimeException("没有数据");
            }
            storeView.setTotalCount(list.size());
            storeView.setTotalSales(list.stream().map(OrderProduct::getOrderAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
            this.popularFood(storeId,list);
            List<OrderProduct> orderProducts = orderProductMapper.selectList(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getStoreId, storeId).orderByDesc(OrderProduct::getCreateTime).in(OrderProduct::getOrderState, 4,8).last("limit 10"));
            Integer rate = 0;
            for (OrderProduct orderProduct : orderProducts) {
                Comment comment = commentMapper.selectOne(new LambdaQueryWrapper<Comment>().eq(Comment::getOrderId, orderProduct.getOrderId()).eq(Comment::getStoreId, storeId));
                if (comment!=null){
                    rate+=comment.getRate();
                }
            }
            Integer newRate = rate/ orderProducts.size();
            storeView.setRate(newRate);
            store.setStoreScore(String.valueOf(newRate));
            storeView.setPopularProduct(String.valueOf(redisUtil.zrerange(RedisKey.saveStorePopularFood(String.valueOf(storeId)),0,1)));
            storeVIewMapper.updateById(storeView);
            storeService.updateById(store);
        }
    }
    public void popularFood(Long storeId,List<OrderProduct> list) throws Exception {
        for (OrderProduct orderProduct : list) {
            List<ProductForm> productForms = JSONUtil.toList(orderProduct.getProductIds(), ProductForm.class);
            productForms.forEach(productForm -> {
                if (redisUtil.score(RedisKey.saveStorePopularFood(String.valueOf(storeId)),productForm.getProductId())==null){
                    redisUtil.zadd(RedisKey.saveStorePopularFood(String.valueOf(storeId)), productForm.getProductId(), 1);
                }else {
                    redisUtil.zincrby(RedisKey.saveStorePopularFood(String.valueOf(storeId)), productForm.getProductId(),1);
                }
            });
        }

    }

    @Override
    public void saveErrorOrder(Map<String, String> map) throws Exception {
        String orderId = map.get("orderId");
        OrderProduct one = this.getOne(new LambdaQueryWrapper<OrderProduct>().eq(OrderProduct::getOrderId, orderId));
        if (null != one){
            one.setOrderState(OrderStatus.ORDER_ERROR);
            this.updateById(one);
            OrderLog orderLog = new OrderLog();
            orderLog.setOrderId(one.getOrderId());
            orderLog.setStatus(OrderStatus.ORDER_ERROR.toString());
            orderLog.setOrderDesc(map.get("subMsg"));
            orderLog.setCreateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            orderLogMapper.insert(orderLog);
        }

    }

}
